package com.hzlj.position.locate.dao;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fz.common.base.converter.QueryWrapperConverterPlus;
import com.fz.common.base.core.JsonUtils;
import com.fz.common.base.core.db.function.IFUtil;
import com.fz.common.base.core.db.function.ToCharUtil;
import com.fz.common.base.core.db.function.ToNumberUtil;
import com.fz.common.base.dto.SortParamDTO;
import com.google.common.collect.Lists;
import com.hzlj.position.config.common.model.JzJbxxDeviceBind;
import com.hzlj.position.config.mapper.JzJbxxDeviceBindMapper;
import com.hzlj.position.locate.common.dto.position.PositionHandleDTO;
import com.hzlj.position.locate.common.dto.position.PositionKeyDTO;
import com.hzlj.position.locate.common.dto.positionNewest.PositionNewestQueryParamDTO;
import com.hzlj.position.locate.common.dto.positionNewest.PositionNewestQueryResultDTO;
import com.hzlj.position.locate.common.dto.positionNewest.PositionNewestQuerySimpleResultDTO;
import com.hzlj.position.locate.common.model.Position;
import com.hzlj.position.locate.common.model.PositionNewest;
import com.hzlj.position.locate.mapper.PositionNewestMapper;
import com.hzlj.sqjz.jz.common.constant.JzJoin;
import com.hzlj.sqjz.jz.common.model.JzJbxx;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 定位记录-分表(PositionNewest)表操作类
 *
 * @author lifh
 * @date 2023-03-16 21:48:44
 */
@Repository
public class PositionNewestDao extends ServiceImpl<PositionNewestMapper, PositionNewest> {
    @Resource
    private PositionNewestMapper positionNewestMapper;
    @Resource
    private JzJbxxDeviceBindMapper jzJbxxDeviceBindMapper;


    public PositionNewestQueryResultDTO getPositionNewestByJzId(String jzId) {
        return QueryWrapperConverterPlus.of(positionNewestMapper)
                .selectOne(PositionNewestQueryResultDTO.class, null, null, q -> {
                    q.eq(Position::getJzId, jzId)
                            .isNotNull(Position::getLatitude)
                            .isNotNull(Position::getLongitude)
                            .orderByDesc(PositionNewest::getPositionTime);
                });
    }


    public List<PositionNewestQuerySimpleResultDTO> getPositionNewestByIds(List<String> ids) {
        return QueryWrapperConverterPlus.of(positionNewestMapper)
                .list(PositionNewestQuerySimpleResultDTO.class, null, q ->
                        q.in(PositionNewest::getId, ids)
                );
    }

    public List<String> getMaxIdsByJzIds(List<String> jzIds) {
        List<String> list = QueryWrapperConverterPlus.of(positionNewestMapper)
                .list(String.class, null, q ->
                        q.select("MAX(id) id")
                                .in(PositionNewest::getJzId, jzIds)
                                .groupBy(PositionNewest::getJzId)
                );
        if (ObjectUtil.isEmpty(list)) {
            return Lists.newArrayList();
        }
        return list;
    }


    public void handle(PositionHandleDTO dto) {
        String warningType = ToCharUtil.format(ToNumberUtil.format("warning_type") + "+50");
        warningType = IFUtil.format("warning=1", warningType, "warning_type");
        LambdaUpdateWrapper<PositionNewest> updateWrapper = new UpdateWrapper<PositionNewest>().lambda()
                .set(PositionNewest::getUpdateTime, new Date())
                .set(PositionNewest::getHandleStatus, dto.getHandleStatus())
                .set(PositionNewest::getHandleTime, dto.getHandleTime())
                .set(ObjectUtil.isNotEmpty(dto.getHandleExt()), PositionNewest::getHandleExt, JsonUtils.obj2json(dto.getHandleExt()))
                .set(ObjectUtil.isNotEmpty(dto.getSysCheck()), PositionNewest::getSysCheck, dto.getSysCheck())
                .setSql(Boolean.TRUE.equals(dto.getNormal()), "warning_type=" + warningType)
                .set(Boolean.TRUE.equals(dto.getNormal()), PositionNewest::getWarning, false)
                .in(PositionNewest::getId, dto.getKeys().stream().map(PositionKeyDTO::getId).collect(Collectors.toList()));
        this.update(updateWrapper);
    }

    public void handleSysCheck(PositionHandleDTO dto) {
        LambdaUpdateWrapper<PositionNewest> updateWrapper = new UpdateWrapper<PositionNewest>().lambda()
                .set(PositionNewest::getUpdateTime, new Date())
                .set(PositionNewest::getSysCheck, dto.getSysCheck())
                .in(PositionNewest::getId, dto.getKeys().stream().map(PositionKeyDTO::getId).collect(Collectors.toList()));
        this.update(updateWrapper);
    }

    public Date getPositionTime(String jzId, String deviceCode, String channel) {
        return QueryWrapperConverterPlus.of(positionNewestMapper)
                .selectOneField(Date.class, q -> {
                    q.select(PositionNewest::getPositionTime)
                            .eq(PositionNewest::getJzId, jzId)
                            .eq(PositionNewest::getDeviceCode, deviceCode)
                            .eq(PositionNewest::getChannel, channel);
                });
    }

    /**
     * 查询列表：不分页
     */
    public List<PositionNewestQueryResultDTO> listPositionNewest(String jgCode) {
        PositionNewestQueryParamDTO params = new PositionNewestQueryParamDTO()
                .setJgCode(jgCode);
        return QueryWrapperConverterPlus.of(jzJbxxDeviceBindMapper)
                .innerJoin(JzJbxx.class, JzJoin.zj(JzJbxxDeviceBind::getJzId))
                .leftJoin(PositionNewest.class, on -> on
                        .eq(PositionNewest::getJzId, JzJbxxDeviceBind::getJzId)
                        .eq(PositionNewest::getDeviceCode, JzJbxxDeviceBind::getDeviceCode)
                        .eq(PositionNewest::getChannel, JzJbxxDeviceBind::getChannel)
                )
                .list(PositionNewestQueryResultDTO.class, params, SortParamDTO.of(false, true, PositionNewest::getId));
    }

}

